package com.yanqu.road.server.gameplayer.module.activity.oldplayerreturn;

import com.yanqu.road.entity.activity.ActivityConditionInfo;
import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.UserActivityConditionData;
import com.yanqu.road.entity.activity.oldplayerreturn.*;
import com.yanqu.road.entity.config.goods.MallInfo;
import com.yanqu.road.entity.enums.*;
import com.yanqu.road.entity.player.ReturnData;
import com.yanqu.road.entity.task.args.PlayerReturnArgs;
import com.yanqu.road.logic.bussiness.activity.OldPlayerReturnBusiness;
import com.yanqu.road.logic.bussiness.log.LogBussiness;
import com.yanqu.road.logic.config.ChannelConfig;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.logic.redis.RedisUserServerList;
import com.yanqu.road.pb.activity.OldPlayerReturnProto;
import com.yanqu.road.pb.player.PlayerProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.ActivityModule;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.CardModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.logic.activity.BaseActivityData;
import com.yanqu.road.server.logic.activity.condition.BaseActivityCondition;
import com.yanqu.road.server.logic.mail.MailManager;
import com.yanqu.road.server.manger.MultipleLanguageMgr;
import com.yanqu.road.server.manger.ServerLanguageMgr;
import com.yanqu.road.server.manger.VipMgr;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.activity.oldplayerreturn.OldPlayerReturnMgr;
import com.yanqu.road.server.manger.config.MallMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.pb.PlayerPb;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.CrossProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author ：zfr
 * @date ：2021/12/6 15:19
 */
public class OldPlayerReturnModule extends GeneralModule {

    private List<Long> serverIdList = new ArrayList<>();    //玩家存在角色的区服id列表

    private boolean loadServerIdListOver = false;   //加载过了其他角色的区服列表

    // serverId - userId - info
    private Map<Long, Map<Long, OldPlayerReturnProto.RoleUserInfoTemp>> otherRoleInfoMap = new ConcurrentHashMap<>(); //回归角色信息列表

    private int lastSyncSize = 0;   //上一次同步的列表大小

    private Map<Long, Long> serverNeedSyncTime = new HashMap<>(); //需要继续同步的区服以及同步时间

    private Map<Integer, OldPlayerReturnShopLimit> mallLimitMap = new ConcurrentHashMap<>();

    private Map<Integer, OldPlayerReturnTaskRewardData> conditionRewardMap = new HashMap<>();

    public OldPlayerReturnModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        loadServerIdList();
        loadMallLimitMap();
        loadConditionRewardMap();
        return true;
    }

    public void loadMallLimitMap() {
        if (OldPlayerReturnMgr.getNowActivityType() == OldPlayerReturnActivityType.NEW_ACTIVITY.getValue()) {
            mallLimitMap = OldPlayerReturnBusiness.getShopAddLimitMap(getUserId());
        }
    }

    public void loadConditionRewardMap() {
        if (OldPlayerReturnMgr.getNowActivityType() == OldPlayerReturnActivityType.NEW_ACTIVITY.getValue()) {
            ActivityInfo activityInfo = OldPlayerReturnMgr.getActivityInfo();
            if (activityInfo != null) {
                conditionRewardMap = OldPlayerReturnBusiness.getOldPlayerReturnTaskRewardData(activityInfo.getActivityId(), getUserId());
            }
        }
    }

    public void loadServerIdList() {
        //有活动 且新区 才需要去拉列表
        if (!loadServerIdListOver && ActivityMgr.activityInTime(OldPlayerReturnMgr.getActivityInfo()) && OldPlayerReturnMgr.checkOpenServerDays(player.getUserInfo().getRegisterTime())) {
            Set<String> redisServerIds = RedisUserServerList.getPlayerServerList(player.getUserInfo().getOpenId());
            List<Long> tempList = new ArrayList<>();
            for (String redisServerId : redisServerIds) {
                long serverId = Long.parseLong(redisServerId);
                if (serverId != GameServer.getInstance().getServerId()){
                    tempList.add(serverId);
                }
            }
            serverIdList = tempList;
            loadServerIdListOver = true;
        }
    }

    @Override
    public void afterLogin() {

    }

    @Override
    public boolean afterLoadData() {
        return false;
    }

    @Override
    public void loginSendMsg() {
        //同步客户端事件配置 其他配置走通用协议同步
        syncEventConfig();

        //请求跨服获取其他区服回归玩家信息
        //syncOtherReturnRoleInfo();
        //将回归角色列表同步给客户端 这两步也有通过定时器定时同步
        syncClientOtherReturnRoleInfo();

        //同步新区新号绑定的活动数据
        syncNewServerBindMsg();
        //同步回归角色的活动数据
        syncReturnPlayerData();

        //自动发奖 只有老号要
        if (OldPlayerReturnMgr.getNowActivityType() == OldPlayerReturnActivityType.OLD_ACTIVITY.getValue()) {      //只有老版本要补发
            autoSendReturnConditionReward();
        }
        autoSendBindConditionReward();
    }

    public void syncNewActivityData() {
        //第一次进来的时候在sync内拿不到回归信息
        if (OldPlayerReturnMgr.getNowActivityType() == OldPlayerReturnActivityType.NEW_ACTIVITY.getValue()) {
            //同步一下限购次数增加
            addMallLimitAllSync();
            //同步免费月卡和便宜月卡
            syncUserFreeCardAndCheapCard();
            //同步任务吧
            syncUserLoginTaskReward();
        }
    }

    public void syncMsg() {
        //同步客户端事件配置 其他配置走通用协议同步
        syncEventConfig();

        //请求跨服获取其他区服回归玩家信息
        //syncOtherReturnRoleInfo();
        //将回归角色列表同步给客户端 这两步也有通过定时器定时同步
        syncClientOtherReturnRoleInfo();

        //同步新区新号绑定的活动数据
        syncNewServerBindMsg();
        //同步回归角色的活动数据
        syncReturnPlayerData();

        //自动发奖 只有老号要
        if (OldPlayerReturnMgr.getNowActivityType() == OldPlayerReturnActivityType.OLD_ACTIVITY.getValue()) {      //只有老版本要补发
            autoSendReturnConditionReward();
        }
        autoSendBindConditionReward();
        if (OldPlayerReturnMgr.getNowActivityType() == OldPlayerReturnActivityType.NEW_ACTIVITY.getValue()) {
            //同步一下限购次数增加
            addMallLimitAllSync();
            //同步免费月卡和便宜月卡
            syncUserFreeCardAndCheapCard();
            //同步任务吧
            syncUserLoginTaskReward();
        }
    }

    @Override
    public boolean saveData() {
        for (OldPlayerReturnShopLimit limit : mallLimitMap.values()) {
            if (limit.isInsertOption()) {
                OldPlayerReturnBusiness.addOldPlayerReturnShopLimit(limit);
            } else if (limit.isUpdateOption()) {
                OldPlayerReturnBusiness.updateOldPlayerReturnShopLimit(limit);
            }
        }
        for (OldPlayerReturnTaskRewardData taskReward : conditionRewardMap.values()) {
            if (taskReward.isInsertOption()) {
                OldPlayerReturnBusiness.addOldPlayerReturnTaskRewardData(taskReward);
            } else if (taskReward.isUpdateOption()) {
                OldPlayerReturnBusiness.updateOldPlayerReturnTaskRewardData(taskReward);
            }
        }

        return true;
    }

    /**
     * 判断玩家是否回归
     *
     * @param lastLoginTime
     */
    public void playerReturn(long lastLoginTime) {

        String noTriggerActivityOldPlayerReturnTime = ChannelConfig.CAN_NO_TRIGGER_ACTIVITY_OLD_PLAYER_RETURN_TIME;
        if (!noTriggerActivityOldPlayerReturnTime.equals("0")) {
            List<String> timeList = StringUtils.stringToStringList(noTriggerActivityOldPlayerReturnTime, "-");
            if (timeList.size() == 2) {
                long startTime = StringUtils.string2longSafe(timeList.get(0), 0);
                long endTime = StringUtils.string2longSafe(timeList.get(1), 0);
                if (System.currentTimeMillis() > startTime && System.currentTimeMillis() <= endTime) {
                    return;
                }
            }
        }
        //回归状态重置
        OldPlayerReturnMgr.resetReturnState(player);
        whiteTriggerActivity();
        //系统是否解锁
        if (!SystemOpenMgr.systemOpen(player, eSystemId.OldPlayerReturn.getValue())) {
            return;
        }
        //如果被封了半个月或者以上 不给绑定 【【V7.4】被封禁账号无法继承VIP - 服务端】https://www.tapd.cn/67122645/prong/tasks/view/1167122645001198139
        if (player.getUserInfo().getBlackListEndTime() > (System.currentTimeMillis() + (DateHelper.DAY_MILLIONS * 15))) {
            log.error("玩家{}由于被封禁 不能触发回归,但是不能登录应该走不到这里",player.getUserId());
            return;
        }

        ActivityInfo activityInfo = OldPlayerReturnMgr.getActivityInfo();
        //判断是否有活动
        if (ActivityMgr.activityInTime(activityInfo)) {
            //身份等级是否足够
            ActivityConfig config = OldPlayerReturnMgr.getActivityConfig("RETURN_OPEN_LIMIT");
            if (config == null) {
                log.debug("回归身份等级配置不存在");
                return;
            }
            if (player.getTitleId() < Integer.parseInt(config.getValue().split("\\|")[0])) {
                return;
            }
            OldPlayerReturnUserData userData = OldPlayerReturnMgr.getUserData(player.getUserId());
            long returnTime = 0;
            if (lastLoginTime == 0) {
                return;
            }

            //如果还未触发回归 拿当前的时间去比较
            if (userData == null || !userData.isReturn()) {
                returnTime = System.currentTimeMillis();

                //已经触发回归 检测一下是否还在回归有效期内
            } else if (OldPlayerReturnMgr.checkReturnEffectiveTime(userData.getReturnTime())
                    && activityInfo.getActivityId() == userData.getActivityId()) {
                //可能是新号绑定触发的回归 这个角色登录后也要触发一下回归任务 回归时间是绑定的时间
                returnTime = userData.getReturnTime();
            }

            //计算出离线的天数 向下取整(案子写的)
            int offlineDays = (int) ((returnTime / 1000 - lastLoginTime) / DateHelper.DAY_SECONDS);
            if (offlineDays < 0) {
                return;
            }
            PlayerReturnArgs args = new PlayerReturnArgs(offlineDays, returnTime);
            //通知活动的离线任务
            player.notifyListener(eGamePlayerEventType.OldPlayerReturnOfflineDays.getValue(), args);
        }
    }

    /**
     * 请求跨服获取其他区服的回归角色信息
     */
    public void syncOtherReturnRoleInfo() {
        OldPlayerReturnUserData userData = OldPlayerReturnMgr.getUserData(player.getUserId());
        if (userData != null && userData.isAlreadyBind()) {
            return;
        }
        if (!loadServerIdListOver) {
            loadServerIdList();
        }
        List<Long> needSyncList = new ArrayList<>();
        for (Long serverId : serverIdList) {
            boolean needSync = true;
            for (Map.Entry<Long, Long> entry : serverNeedSyncTime.entrySet()) {
                if (Objects.equals(entry.getKey(), serverId)) {
                    if (System.currentTimeMillis() / 1000 < entry.getValue()) {
                        needSync = false;
                    }
                }
            }
            if (needSync) {
                needSyncList.add(serverId);
            }
        }
        //其他区服没有角色(或者是都请求过了) 就不用请求跨服了
        if (needSyncList.size() == 0) {
            return;
        }

        OldPlayerReturnProto.GetOtherReturnRoleInfoReqToCrossMsg.Builder reqMsg = OldPlayerReturnProto.GetOtherReturnRoleInfoReqToCrossMsg.newBuilder();
        reqMsg.addAllGoalServerId(needSyncList);
        reqMsg.setOpenId(player.getUserInfo().getOpenId());
        player.sendPacket(CrossProtocol.C_CROSS_GET_OTHER_RETURN_ROLE_INFO, reqMsg);
    }

    /**
     * 跨服返回其他区服的回归角色信息
     *
     * @param bindServerId  返回的区服
     * @param userInfos     回归角色信息
     * @param canReturnTime
     */
    public void syncRoleInfoResp(long bindServerId, List<OldPlayerReturnProto.RoleUserInfoTemp> userInfos, long canReturnTime) {
        boolean success = false;
        for (OldPlayerReturnProto.RoleUserInfoTemp userInfo : userInfos) {
            if (!otherRoleInfoMap.containsKey(userInfo.getServerId())) {
                otherRoleInfoMap.put(userInfo.getServerId(), new ConcurrentHashMap<>());
            }
            otherRoleInfoMap.get(userInfo.getServerId()).put(userInfo.getUserId(), userInfo);
            success = true;
        }
        if (success || canReturnTime == -1) {
            //请求到了就移除掉 不重复请求（再请求也是一样的结果）
            serverIdList.remove(bindServerId);
        }
        serverNeedSyncTime.put(bindServerId, canReturnTime);
    }

    /**
     * 同步客户端回归角色信息
     */
    private void syncClientOtherReturnRoleInfo() {
        boolean needSync = false;
        OldPlayerReturnUserData userData = OldPlayerReturnMgr.getUserData(player.getUserId());
        OldPlayerReturnProto.OtherRoleListSyncMsg.Builder syncMsg = OldPlayerReturnProto.OtherRoleListSyncMsg.newBuilder();
        Map<Integer, OldReturnWhite> playerWhiteMap = OldPlayerReturnMgr.getPlayerWhiteMap(player.getUserId());
        if (playerWhiteMap != null && (userData == null || !userData.isAlreadyBind())) {
            OldReturnWhite returnWhite = playerWhiteMap.get(OldReturnWhiteTypeEnum.NEW.getWhiteType());
            if (returnWhite != null) {
                syncMsg.setIsWhitePlayer(true);
                syncMsg.setTotalVipExp((int) returnWhite.getReturnVipExp());
                needSync = true;
            }
        }

        if (otherRoleInfoMap.size() == 0 && !needSync) {
            return;
        }

        for (Map<Long, OldPlayerReturnProto.RoleUserInfoTemp> roleInfoMap : new ArrayList<>(otherRoleInfoMap.values())) {
            for (OldPlayerReturnProto.RoleUserInfoTemp roleInfo : roleInfoMap.values()) {
                syncMsg.addOtherRoleInfo(roleInfo);
            }
        }
        player.sendPacket(ClientProtocol.U_SYNC_RETURN_ROLE_INFO_LIST, syncMsg);
    }

    /**
     * 绑定回归角色
     *
     * @param serverId 绑定的区服id
     * @param userId   绑定的玩家id
     * @return ret
     */
    public int bindReturnRole(long serverId, long userId) {
        //系统未解锁
        if (!SystemOpenMgr.systemOpen(player, eSystemId.OldPlayerReturn.getValue())) {
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }
        //活动不存在
        if (!ActivityMgr.activityInTime(OldPlayerReturnMgr.getActivityInfo())) {
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }
        //不在开服限制时间之内
        if (!OldPlayerReturnMgr.checkOpenServerDays(player.getUserInfo().getRegisterTime())) {
            return GameErrorCode.E_PLAYER_RETURN_OPEN_SERVER_DAYS_LIMIT;
        }
        OldPlayerReturnUserData userData = OldPlayerReturnMgr.getUserData(getUserId());
        //已经绑定过了
        if (userData != null && userData.isAlreadyBind()) {
            return GameErrorCode.E_PLAYER_RETURN_ALREADY_BIND_OTHER_ROLE;
        }
        //请求的目标不在该玩家回归角色列表中
        if (!otherRoleInfoMap.containsKey(serverId) || !otherRoleInfoMap.get(serverId).containsKey(userId)) {
            return GameErrorCode.E_PLAYER_RETURN_BIND_ROLE_NOT_IN_LIST;
        }
        //上传跨服去目标服绑定角色
        OldPlayerReturnProto.BindReturnRoleReqCrossMsg.Builder reqMsg = OldPlayerReturnProto.BindReturnRoleReqCrossMsg.newBuilder();
        reqMsg.setServerId(serverId);
        reqMsg.setUserId(userId);
        reqMsg.setOriOpenId(player.getUserInfo().getOpenId());
        reqMsg.setOriUserInfo(PlayerPb.parsePlayerBaseTempMsg(player.getUserInfo()));
        player.sendPacket(CrossProtocol.C_CROSS_BIND_RETURN_ROLE, reqMsg);
        return 0;
    }

    /**
     * 绑定成功返回
     *
     * @param bindServerId 绑定的区服id
     * @param bindUserId   绑定的玩家id
     * @param bindUserInfo 绑定的玩家信息
     * @param vipExp       绑定的玩家vip经验
     * @return ret
     */
    public int bindReturnRoleSuccessResp(long bindServerId, long bindUserId, PlayerProto.PlayerBaseTempMsg bindUserInfo, long vipExp) {
        ActivityInfo activityInfo = OldPlayerReturnMgr.getActivityInfo();
        //完犊子 活动过期了
        if (!ActivityMgr.activityInTime(activityInfo)) {
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }
        ActivityConfig returnVipExpLimit = OldPlayerReturnMgr.getActivityConfig("RETURN_VIP_EXP_LIMIT");
        ActivityConfig returnGoldLimit = OldPlayerReturnMgr.getActivityConfig("RETURN_GOLD_LIMIT");
        if (returnVipExpLimit == null || returnGoldLimit == null || returnVipExpLimit.getValue().isEmpty() || returnGoldLimit.getValue().isEmpty()) {
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }
        String config = returnVipExpLimit.getValue() + "|" + returnGoldLimit.getValue();
        //绑定一下
        OldPlayerReturnUserData userData = OldPlayerReturnMgr.getUserData(player.getUserId());
        if (userData == null) {
            userData = new OldPlayerReturnUserData();
            userData.setUserId(player.getUserId());
            userData.setActivityType(activityInfo.getType());
            userData.setRmbMallLimit(new ConcurrentHashMap<>());
            userData.setInsertOption();
            OldPlayerReturnMgr.addUserData(userData);
        }
        userData.setActivityId(activityInfo.getActivityId());
        userData.setOldServerId(bindServerId);
        userData.setOldUserId(bindUserId);
        userData.setOldUserBaseInfo(PlayerBasePb.parseToUserBaseInfo(bindUserInfo));
        userData.setVipExp(vipExp);
        userData.setReturnVipExpConfig(config);
        userData.setOldTime(System.currentTimeMillis());
        //通知一下绑定的任务 可以领奖
        player.notifyListener(eGamePlayerEventType.OldPlayerReturnBindRole.getValue(), 1);

        //同步新区新号绑定的活动数据
        syncNewServerBindMsg();
        return 0;
    }

    /**
     * 定时器同步回归角色信息列表给客户端
     */
    public void checkNeedSync() {
//        int nowSize = otherRoleInfoMap.size();
        //定时器这边的同步 如果不比上一次同步的量多 就不用再同步了
//        if (nowSize > lastSyncSize) {
        syncClientOtherReturnRoleInfo();
//            lastSyncSize = nowSize;
//        }
    }

    /**
     * 同步绑定信息
     */
    private void syncNewServerBindMsg() {
        ActivityInfo activityInfo = OldPlayerReturnMgr.getActivityInfo();
        //活动存在才同步
        if (ActivityMgr.activityInTime(activityInfo)) {
            OldPlayerReturnUserData userData = OldPlayerReturnMgr.getUserData(getUserId());
            //有绑定的才同步
            if (userData != null && userData.isAlreadyBind() && OldPlayerReturnMgr.checkOpenServerDays(player.getUserInfo().getRegisterTime()) && activityInfo.getActivityId() == userData.getActivityId()) {
                OldPlayerReturnProto.NewServerBindSyncMsg.Builder syncMsg = OldPlayerReturnProto.NewServerBindSyncMsg.newBuilder();
                if (userData.getOldUserId() != 0) {
                    OldPlayerReturnProto.RoleUserInfoTemp.Builder bindUser = OldPlayerReturnProto.RoleUserInfoTemp.newBuilder();
                    bindUser.setServerId(userData.getOldServerId());
                    bindUser.setUserId(userData.getOldUserId());
                    bindUser.setUserInfo(PlayerBasePb.parsePlayerBaseTempMsg(userData.getOldUserBaseInfo()));
                    syncMsg.setBindUserInfo(bindUser);
                }
                String reward = "";
                int leftDays = 0;

                //算一下 是绑定的第几天
                long timeMillis = DateHelper.getTodayZeroTimeStamp() - DateHelper.getZeroTimeStamp(userData.getOldTime());
                int nowDays = (int) (timeMillis / DateHelper.DAY_MILLIONS + 1);

                //计算当日可以领取的绑定奖励
                ReturnData returnData = OldPlayerReturnMgr.calcTodayBindReward(nowDays, userData);
                if (returnData.getParams().size() > 0) {
                    reward = returnData.getParams().get(0);
                    leftDays = Integer.parseInt(returnData.getParams().get(1));
                }
                syncMsg.setTodayReward(reward);
                syncMsg.setLeftDays(leftDays);
                syncMsg.setIsWhiteBind(userData.isWhiteBindEffect());
                OldReturnWhite playerWhite = OldPlayerReturnMgr.getPlayerWhite(player.getUserId(), OldReturnWhiteTypeEnum.NEW.getWhiteType());
                if (playerWhite != null && userData.isWhiteBindEffect()) {
                    syncMsg.setTotalVipExp((int) playerWhite.getReturnVipExp());
                }
                player.sendPacket(ClientProtocol.U_NEW_SERVER_BIND_DATA_SYNC, syncMsg);
            }
        }
    }

    /**
     * 检查是否是有效的回归角色
     *
     * @param userData 玩家数据
     * @return ret
     */
    public int checkReturnRoleIsEffective(OldPlayerReturnUserData userData) {
        ActivityInfo activityInfo = OldPlayerReturnMgr.getActivityInfo();
        //活动不存在
        if (!ActivityMgr.activityInTime(activityInfo)) {
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }
        //不是回归玩家
        if (userData == null || !userData.isReturn()) {
            return GameErrorCode.E_PLAYER_RETURN_NOT_RETURN_ROLE;
        }
        //回归有效期已经过了
        if (!OldPlayerReturnMgr.checkReturnEffectiveTime(userData.getReturnTime())) {
            return GameErrorCode.E_PLAYER_RETURN_RETURN_TIME_OVER;
        }
        //不是这个活动触发的回归
        if (activityInfo.getActivityId() != userData.getActivityId()) {
            return GameErrorCode.E_PLAYER_RETURN_NOT_RETURN_ROLE;
        }
        return 0;
    }

    /**
     * 领取事件奖励
     *
     * @param choose 选择（0；1）
     * @return ret
     */
    public int getEventReward(int choose) {
        OldPlayerReturnUserData userData = OldPlayerReturnMgr.getUserData(getUserId());
        int ret = checkReturnRoleIsEffective(userData);
        if (ret != 0) {
            return ret;
        }
        assert userData != null;
        //已领奖
        if (userData.isGetEventReward()) {
            return GameErrorCode.E_PLAYER_RETURN_EVENT_IS_GET_REWARD;
        }
        int eventId = userData.getEventId();
        OldPlayerReturnEventConfig eventConfig = OldPlayerReturnMgr.getEventConfig(eventId);
        if (eventConfig == null) {  //会返回空 做一下判空
            return GameErrorCode.E_PLAYER_RETURN_EVENT_CONFIG_NO_FOUND;
        }
        OldPlayerReturnProto.GetOldPlayerReturnEventRewardRespMsg.Builder respMsg = OldPlayerReturnProto.GetOldPlayerReturnEventRewardRespMsg.newBuilder();
        respMsg.setRet(0);

        //根据选择 获取奖励
        String[] rewardList = eventConfig.getReward().split("\\|");
        String reward = rewardList[choose];

        //先设状态再发奖
        userData.setGetEventReward(true);
        userData.setLastRefreshTime(System.currentTimeMillis());
        player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.Activity, eLogMoneyType.OldPlayerReturnGetEventReward);

        respMsg.setReward(reward);
        player.sendPacket(ClientProtocol.U_OLD_PLAYER_RETURN_GET_EVENT_REWARD, respMsg);

        //同步回归角色的活动数据
        syncReturnPlayerData();
        return 0;
    }

    /**
     * 同步回归玩家活动数据
     */
    void syncReturnPlayerData() {
        OldPlayerReturnUserData userData = OldPlayerReturnMgr.getUserData(getUserId());
        //不是有效的回归玩家 不用同步了
        if (checkReturnRoleIsEffective(userData) != 0) {
            return;
        }
        OldPlayerReturnProto.OldPlayerReturnSyncMsg.Builder syncMsg = OldPlayerReturnProto.OldPlayerReturnSyncMsg.newBuilder();
        assert userData != null;
        //有新号绑定
        if (userData.getNewUserId() != 0) {
            OldPlayerReturnProto.RoleUserInfoTemp.Builder userTemp = OldPlayerReturnProto.RoleUserInfoTemp.newBuilder();
            userTemp.setServerId(userData.getNewServerId());
            userTemp.setUserId(userData.getNewUserId());
            userTemp.setUserInfo(PlayerBasePb.parsePlayerBaseTempMsg(userData.getNewUserBaseInfo()));
            syncMsg.setNewRoleUserInfo(userTemp);
        }

        //事件数据
        syncMsg.setEventId(userData.getEventId());
        syncMsg.setIsGetEventReward(userData.isGetEventReward());
        syncMsg.setPlaceId(StringUtils.isNullOrEmpty(userData.getPlaceId()) ? "" : userData.getPlaceId());
        player.sendPacket(ClientProtocol.U_RETURN_PLAYER_DATA_SYNC, syncMsg);
    }

    /**
     * 事件刷新
     */
    public void eventRefresh() {
        OldPlayerReturnUserData userData = OldPlayerReturnMgr.getUserData(getUserId());
        //不是有效的回归玩家 不用刷新了
        if (checkReturnRoleIsEffective(userData) != 0) {
            return;
        }
        assert userData != null;
        //已经生成事件并且未领奖 就不用重新刷新
        if (userData.getEventId() != 0 && !userData.isGetEventReward()) {
            return;
        }
        ActivityConfig config = OldPlayerReturnMgr.getActivityConfig("RETURN_EVENT_REFRESH_TIME");
        if (config == null) {
            return;
        }
        BigDecimal refreshHourTime = new BigDecimal(config.getValue());
        //距离上一次刷新并领奖的时间 超过了配置的刷新时间 就刷
        if (System.currentTimeMillis() - userData.getLastRefreshTime() >= refreshHourTime.multiply(BigDecimal.valueOf(DateHelper.HOUR_MILLIONS)).longValue()) {
            //刷新
            OldPlayerReturnEventConfig eventConfig = OldPlayerReturnMgr.randomEvent();
            if (eventConfig == null) {
                return;
            }
            //随机位置 改成了 固定位置了
            String placeIdList = eventConfig.getPlaceIdList();
            userData.setGetEventReward(false);
            userData.setEventId(eventConfig.getEventId());
            userData.setPlaceId(placeIdList);

            //同步回归角色的活动数据
            syncReturnPlayerData();
        }
    }

    /**
     * 同步事件配置
     */
    private void syncEventConfig() {
        String language = player.getLanguage();
        OldPlayerReturnProto.EventConfigSyncMsg.Builder syncMsg = OldPlayerReturnProto.EventConfigSyncMsg.newBuilder();
        ActivityInfo activityInfo = OldPlayerReturnMgr.getActivityInfo();
        if (!ActivityMgr.activityInTime(activityInfo)) {
            return;
        }
        syncMsg.setActivityId(activityInfo.getActivityId());
        Map<Integer, OldPlayerReturnEventConfig> eventConfigMap = OldPlayerReturnMgr.getEventConfigMap();
        for (OldPlayerReturnEventConfig eventConfig : eventConfigMap.values()) {
            OldPlayerReturnProto.EventConfigTemp.Builder temp = OldPlayerReturnProto.EventConfigTemp.newBuilder();
            temp.setEventId(eventConfig.getEventId());
            temp.setNpcId(eventConfig.getNpcId());
            temp.setNpcName(ServerLanguageMgr.getContent(eventConfig.getNpcName(), language));
            temp.setName(ServerLanguageMgr.getContent(eventConfig.getName(), language));
            temp.setDesc(ServerLanguageMgr.getContent(eventConfig.getDesc(), language));
            syncMsg.addEventConfig(temp);
        }
        player.sendPacket(ClientProtocol.U_OLD_PLAYER_RETURN_EVENT_CONFIG_SYNC, syncMsg);
    }

    /**
     * 自动补发玩家回归任务奖励
     */
    public synchronized void autoSendReturnConditionReward() {
        OldPlayerReturnUserData userData = OldPlayerReturnMgr.getUserData(getUserId());
        //如果不是回归玩家就不用了
        if (userData == null || !userData.isReturn()) {
            return;
        }
        //玩家回归时候的活动过期了 就不走这边的补发 走活动过期的补发
        int activityId = userData.getActivityId();
        if (OldPlayerReturnMgr.getActivityInfo() == null || OldPlayerReturnMgr.getActivityInfo().getActivityId() != activityId) {
            return;
        }

        //还在回归活动有效期内 不补发 玩家自己领
        if (OldPlayerReturnMgr.checkReturnEffectiveTime(userData.getReturnTime())) {
            return;
        }

        //已经补发过了 也不用了
        if (userData.isSendReturnConditionRewardState()) {
            return;
        }

        //先设置领奖状态
        userData.setSendReturnConditionRewardState(true);
        Property reward = new Property();
        List<BaseActivityCondition> baseActivityConditions = player.getModule(ActivityModule.class).getBaseActivityData(activityId).getBaseActivityConditionList();

        for (BaseActivityCondition baseActivityCondition : baseActivityConditions) {
            //新号绑定奖励这边不补
            if (baseActivityCondition.getConditionType() != eGamePlayerEventType.OldPlayerReturnBindRole.getValue()
                    && baseActivityCondition.isCompleted(player)
                    && !baseActivityCondition.isGetReward()) {
                baseActivityCondition.setGetReward(true);
                reward.addProperty(PropertyHelper.parseStringToProperty(baseActivityCondition.getActivityConditionInfo().getRewardStr()));
            }
        }
        if (!reward.isNothing()) {
            sendMailReward(reward, OldPlayerReturnMgr.getActivityInfo());
        }
    }

    /**
     * 自动补发玩家新号绑定任务奖励
     */
    private void autoSendBindConditionReward() {
        OldPlayerReturnUserData userData = OldPlayerReturnMgr.getUserData(getUserId());
        //没有绑定的就不用了
        if (userData == null || !userData.isAlreadyBind()) {
            return;
        }

        //玩家绑定时候的活动过期了 就不走这边的补发 走活动过期的补发
        int activityId = userData.getActivityId();
        if (OldPlayerReturnMgr.getActivityInfo() == null || OldPlayerReturnMgr.getActivityInfo().getActivityId() != activityId) {
            return;
        }

        //还在绑定活动有效期内 玩家自己领
        if (OldPlayerReturnMgr.checkOpenServerDays(player.getUserInfo().getRegisterTime())) {
            return;
        }

        //已经补发过了
        if (userData.isSendBindConditionRewardState()) {
            return;
        }

        //设置补发完成状态
        userData.setSendBindConditionRewardState(true);
        Property reward = new Property();
        List<BaseActivityCondition> baseActivityConditions = player.getModule(ActivityModule.class).getBaseActivityData(activityId).getBaseActivityConditionList();

        for (BaseActivityCondition baseActivityCondition : baseActivityConditions) {
            //只补发绑定的奖励
            if (baseActivityCondition.getConditionType() == eGamePlayerEventType.OldPlayerReturnBindRole.getValue()
                    && baseActivityCondition.isCompleted(player)
                    && !baseActivityCondition.isGetReward()) {
                baseActivityCondition.setGetReward(true);
                reward.addProperty(PropertyHelper.parseStringToProperty(baseActivityCondition.getActivityConditionInfo().getRewardStr()));
            }
        }
        if (!reward.isNothing()) {
            sendMailReward(reward, OldPlayerReturnMgr.getActivityInfo());
        }
    }

    /**
     * 邮件发奖
     *
     * @param reward       奖励
     * @param activityInfo
     */
    private void sendMailReward(Property reward, ActivityInfo activityInfo) {
        String language = player.getLanguage();
        String mailTitle = StringUtils.format(MultipleLanguageMgr.getContent(MailManager.OLD_PLAYER_RETURN_CONDITION_REWARD_TITLE, language), ActivityMgr.getActivityName(activityInfo, language));
        String mailContent = StringUtils.format(MultipleLanguageMgr.getContent(MailManager.OLD_PLAYER_RETURN_CONDITION_REWARD_CONTENT, language), ActivityMgr.getActivityName(activityInfo, language));
        MailManager.sendMail(player.getUserId(), eMailType.SYSTEM.getValue(), PropertyHelper.parsePropertyToString(reward), mailContent, mailTitle);
    }


    // ---------------------------- 4.7.0 --------------------------------

    /**
     * 白名单触发
     */
    public void whiteTriggerActivity() {
        //有没有在白名单中
        Map<Integer, OldReturnWhite> playerWhiteMap = OldPlayerReturnMgr.getPlayerWhiteMap(player.getUserId());
        if (playerWhiteMap == null) {
            return;
        }
        for (OldReturnWhite returnWhite : playerWhiteMap.values()) {
            if (returnWhite.getWhiteType() == OldReturnWhiteTypeEnum.OLD.getWhiteType()) {
                dealWhiteOldTriggerActivity(returnWhite);
            }
        }
    }

    /**
     * 白名单 新玩家类型触发活动
     *
     * @param returnWhite
     */
    private int dealWhiteNewTriggerActivity(OldReturnWhite returnWhite) {
        ActivityInfo activityInfo = OldPlayerReturnMgr.getActivityInfo();
        //活动过期了
        if (!ActivityMgr.activityInTime(activityInfo)) {
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }
        OldPlayerReturnUserData userData = OldPlayerReturnMgr.getUserData(getUserId());
        //是否绑定过了
        if (userData != null && userData.isAlreadyBind()) {
            return GameErrorCode.E_PLAYER_RETURN_ALREADY_BIND_OTHER_ROLE;
        }
        //不在开服限制时间之内
        if (!OldPlayerReturnMgr.checkOpenServerDays(player.getUserInfo().getRegisterTime())) {
            return GameErrorCode.E_PLAYER_RETURN_OPEN_SERVER_DAYS_LIMIT;
        }
        ActivityConfig returnVipExpLimit = OldPlayerReturnMgr.getActivityConfig("RETURN_VIP_EXP_LIMIT");
        ActivityConfig returnGoldLimit = OldPlayerReturnMgr.getActivityConfig("RETURN_GOLD_LIMIT");
        if (returnVipExpLimit == null || returnGoldLimit == null || returnVipExpLimit.getValue().isEmpty() || returnGoldLimit.getValue().isEmpty()) {
            return GameErrorCode.E_PLAYER_RETURN_VIP_CONFIG_ERROR;
        }
        String config = returnVipExpLimit.getValue() + "|" + returnGoldLimit.getValue();
        if (userData == null) {
            userData = new OldPlayerReturnUserData();
            userData.setUserId(player.getUserId());
            userData.setActivityType(activityInfo.getType());
            userData.setInsertOption();
            OldPlayerReturnMgr.addUserData(userData);
        }
        userData.setVipExp(returnWhite.getReturnVipExp());
        userData.setReturnVipExpConfig(config);
        userData.setOldTime(System.currentTimeMillis());
        userData.setActivityId(activityInfo.getActivityId());
        userData.setWhiteBindEffect(true);
        //通知一下绑定的任务 可以领奖
        player.notifyListener(eGamePlayerEventType.OldPlayerReturnBindRole.getValue(), 1);
        //同步新区新号绑定的活动数据
        syncNewServerBindMsg();
        return 0;
    }

    /**
     * 白名单 老玩家类型触发活动
     *
     * @param returnWhite
     */
    private void dealWhiteOldTriggerActivity(OldReturnWhite returnWhite) {
        ActivityInfo activityInfo = OldPlayerReturnMgr.getActivityInfo();
        //活动过期了
        if (!ActivityMgr.activityInTime(activityInfo)) {
            return;
        }
        //已经回归了
        OldPlayerReturnUserData userData = OldPlayerReturnMgr.getUserData(getUserId());
        if (userData != null && userData.isReturn()) {
            return;
        }
        int needOfflineDays = OldPlayerReturnMgr.getActivity().getNeedOfflineDays();
        PlayerReturnArgs args = new PlayerReturnArgs(needOfflineDays, System.currentTimeMillis());
        //通知活动的离线任务
        player.notifyListener(eGamePlayerEventType.OldPlayerReturnOfflineDays.getValue(), args);
    }

    public int activateWhite() {
        //有没有在白名单中
        Map<Integer, OldReturnWhite> playerWhiteMap = OldPlayerReturnMgr.getPlayerWhiteMap(player.getUserId());
        if (playerWhiteMap == null) {
            return GameErrorCode.E_PLAYER_HAVE_NOT_WHITE_QUALIFICATION;
        }
        return dealWhiteNewTriggerActivity(playerWhiteMap.get(OldReturnWhiteTypeEnum.NEW.getWhiteType()));
    }

    /**
     * 获取离线倍率
     */
    public BigDecimal getTaskOfflineRate() {

        BigDecimal rate = BigDecimal.valueOf(1);
        ActivityInfo activityInfo = OldPlayerReturnMgr.getActivityInfo();
        if (activityInfo == null) {
            return rate;
        }
        BaseActivityData baseActivityData = player.getModule(ActivityModule.class).getBaseActivityData(activityInfo.getActivityId());
        UserActivityConditionData firstUserActivityConditionDataByType = baseActivityData.getFirstUserActivityConditionDataByType(eGamePlayerEventType.OldPlayerReturnOfflineDays.getValue());
        if (firstUserActivityConditionDataByType == null) {
            return rate;
        }
        int offlineDay = firstUserActivityConditionDataByType.getValue().intValue();
        Map<String, ActivityConfig> configMap = OldPlayerReturnMgr.getActivity().getConfigMap();

        rate = BigDecimal.valueOf(offlineDay).divide(BigDecimal.valueOf(configMap.get("RETURN_TASK_OFFLINE_PARAMETER").getIntValue()), 1, BigDecimal.ROUND_DOWN);
        int maxOfflineRate = configMap.get("RETURN_TASK_OFFLINE_PARAMETER_MAX").getIntValue();  //千分比
        if (rate.compareTo(BigDecimal.valueOf(maxOfflineRate / 1000)) > 0) {
            return BigDecimal.valueOf(maxOfflineRate / 1000);
        }
        return rate;
    }

    /**
     * 同步回归玩家每日登录特殊奖励
     */
    public void syncUserLoginTaskReward() {
        if (!checkUserIsReturn()) {
            return;
        }
        if (conditionRewardMap.isEmpty()) {
            generateReturnUserLoginReward(false);
        }
        OldPlayerReturnProto.OldPlayerReturnTaskRewardSync.Builder builder = OldPlayerReturnProto.OldPlayerReturnTaskRewardSync.newBuilder();
        for (OldPlayerReturnTaskRewardData oldPlayerReturnTaskRewardData : conditionRewardMap.values()) {
            OldPlayerReturnProto.OldPlayerReturnTaskReward.Builder singleTaskBuilder = OldPlayerReturnProto.OldPlayerReturnTaskReward.newBuilder();
            singleTaskBuilder.setConditionId(oldPlayerReturnTaskRewardData.getConditionId());
            for (OldPlayerReturnAddtionGood good : oldPlayerReturnTaskRewardData.getConditionReward()) {
                OldPlayerReturnProto.OldPlayerReturnLoginTaskSingleReward.Builder singleRewardBuilder = OldPlayerReturnProto.OldPlayerReturnLoginTaskSingleReward.newBuilder();
                singleRewardBuilder.setReward(good.getReward());
                singleRewardBuilder.setAddition(good.getAddition());
                singleTaskBuilder.addReward(singleRewardBuilder);
            }
            builder.addTaskReward(singleTaskBuilder);
        }
        player.sendPacket(ClientProtocol.U_RETURN_PLAYER_LOGIN_TASK_VALUE_SYNC, builder);

    }


    /**
     * 同步玩家使用月卡时间与是否购买月卡
     */
    public void syncUserFreeCardAndCheapCard() {
        if (!checkUserIsReturn()) {
            return;
        }
        OldPlayerReturnUserData userData = OldPlayerReturnMgr.getUserData(getUserId());
        OldPlayerReturnProto.OldPlayerFreeAndCheapCardSync.Builder builder = OldPlayerReturnProto.OldPlayerFreeAndCheapCardSync.newBuilder();
        builder.setGetFreeCardTime(userData.getGotCardTrialTime());
        builder.setHasBuyCheapCard(userData.isHadBuyCheapCard());
        player.sendPacket(ClientProtocol.U_RETURN_PLAYER_FREE_CHEAP_CARD_DATA_SYNC, builder);
    }

    /**
     * 同步所有限购
     */
    public void addMallLimitAllSync() {
        ActivityInfo activityInfo = OldPlayerReturnMgr.getActivityInfo();
        if (!checkUserIsReturn()) {
            return;
        }
        if (mallLimitMap == null || mallLimitMap.isEmpty()) {
            UserActivityConditionData firstUserActivityConditionDataByType = player.getModule(ActivityModule.class).getBaseActivityData(activityInfo.getActivityId()).getFirstUserActivityConditionDataByType(1152);
            if (firstUserActivityConditionDataByType == null) {
                return;
            }
            int days = firstUserActivityConditionDataByType.getValue().intValue();
            recordPlayerVipLevelAndCalculatRecoverShopTimes(days, false);
        }
        OldPlayerReturnProto.MallAddLimitAllSync.Builder builder = OldPlayerReturnProto.MallAddLimitAllSync.newBuilder();
        for (OldPlayerReturnShopLimit addShop : mallLimitMap.values()) {
            OldPlayerReturnProto.SingleMallAddLimit.Builder singleBuilder = OldPlayerReturnProto.SingleMallAddLimit.newBuilder();
            singleBuilder.setMallId(addShop.getMallId());
            singleBuilder.setHasBuyTime(addShop.getHasBuyTimes());
            singleBuilder.setTotalLimit(addShop.getTotalAddLimit());
            builder.addAddMallLimit(singleBuilder);
        }
        player.sendPacket(ClientProtocol.U_RETURN_PLAYER_RECOVER_MALL_LIMIT_TIME_ALL_SYNC, builder);

    }

    /**
     * 同步单条特殊限购
     */
    public void addMallLimitSync(OldPlayerReturnShopLimit oldPlayerReturnShopLimit) {
        if (oldPlayerReturnShopLimit == null) {
            return;
        }
        OldPlayerReturnProto.MallAddLimitSingleSync.Builder builder = OldPlayerReturnProto.MallAddLimitSingleSync.newBuilder();
        OldPlayerReturnProto.SingleMallAddLimit.Builder singleBuilder = OldPlayerReturnProto.SingleMallAddLimit.newBuilder();
        singleBuilder.setMallId(oldPlayerReturnShopLimit.getMallId());
        singleBuilder.setHasBuyTime(oldPlayerReturnShopLimit.getHasBuyTimes());
        singleBuilder.setTotalLimit(oldPlayerReturnShopLimit.getTotalAddLimit());
        builder.setAddMallLimit(singleBuilder);
        player.sendPacket(ClientProtocol.U_RETURN_PLAYER_RECOVER_MALL_LIMIT_TIME_SINGLE_SYNC, builder);
    }

    /**
     * 回归领取一下免费7天月卡
     */
    public int receiveTrialCard() {
        OldPlayerReturnUserData userData = OldPlayerReturnMgr.getUserData(getUserId());
        ActivityInfo activityInfo = OldPlayerReturnMgr.getActivityInfo();
        //活动不存在
        if (!ActivityMgr.activityInTime(activityInfo)) {
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }
        //不是回归玩家
        if (userData == null || !userData.isReturn()) {
            return GameErrorCode.E_PLAYER_RETURN_NOT_RETURN_ROLE;
        }
        //回归有效期已经过了
        if (!OldPlayerReturnMgr.checkReturnEffectiveTime(userData.getReturnTime())) {
            return GameErrorCode.E_PLAYER_RETURN_RETURN_TIME_OVER;
        }
        //不是这个活动触发的回归
        if (activityInfo.getActivityId() != userData.getActivityId()) {
            return GameErrorCode.E_PLAYER_RETURN_NOT_RETURN_ROLE;
        }
        //已经领取过了
        if (userData.getGotCardTrialTime() != 0) {
            return GameErrorCode.E_PLAYER_RETURN_HAS_RECEIVE_FREE_CARD;
        }
        userData.setGotCardTrialTime(System.currentTimeMillis());
        player.getModule(CardModule.class).oldPlayerCardTrial();
        OldPlayerReturnProto.GetFreeCardRespMsg.Builder builder = OldPlayerReturnProto.GetFreeCardRespMsg.newBuilder();
        builder.setRet(0);
        builder.setGetFreeCardTime(userData.getGotCardTrialTime());
        player.sendPacket(ClientProtocol.U_RETURN_PLAYER_GET_FREE_CARD_TIME, builder);
        return 0;
    }

    /**
     * 记录玩家回归时的vip等级 并且计算找回兑换次数
     */
    public void recordPlayerVipLevelAndCalculatRecoverShopTimes(int offlineDay, boolean force) {
        ActivityInfo activityInfo = OldPlayerReturnMgr.getActivityInfo();
        if (!checkUserIsReturn()) {
            return;
        }
        ActivityConfig param = OldPlayerReturnMgr.getActivityConfig("RETURN_TASK_OFFLINE_PARAMETER_SYSTEM");
        if (param == null) {
            log.error("老玩家回归活动 {} 系统找回离线倍率配置有误!", activityInfo.getActivityId());
            return;
        }
        ActivityConfig vipParam = OldPlayerReturnMgr.getActivityConfig("RETURN_MALL_VIP_PARAMETER");
        if (vipParam == null) {
            log.error("老玩家回归活动 {} vip召回加成配置有误!", activityInfo.getActivityId());
            return;
        }
        boolean hadOldValueThisActivity = false;
        if (mallLimitMap != null && !mallLimitMap.isEmpty()) {
            hadOldValueThisActivity = true;
        }
        if (hadOldValueThisActivity && !force) {
            return;
        }

        int vipAddParam = getVipMultiplier(vipParam.getValue());
        //系统商店
        List<MallInfo> mallInfoList = new ArrayList<>();
        mallInfoList.addAll(MallMgr.getMallInfoListByShopType(ShopType.EstateWarMall.getIntValue()));
        mallInfoList.addAll(MallMgr.getMallInfoListByShopType(ShopType.HuntMall.getIntValue()));
        mallInfoList.addAll(MallMgr.getMallInfoListByShopType(ShopType.TradeWarIntegralMall.getIntValue()));
        mallInfoList.addAll(MallMgr.getMallInfoListByShopType(ShopType.UnionMall.getIntValue()));
        mallInfoList.addAll(MallMgr.getMallInfoListByShopType(ShopType.BanquetMall.getIntValue()));
        mallInfoList.addAll(MallMgr.getMallInfoListByShopType(ShopType.InnMall.getIntValue()));
        mallInfoList.addAll(MallMgr.getMallInfoListByShopType(ShopType.WineryMall.getIntValue()));
        mallInfoList.addAll(MallMgr.getMallInfoListByShopType(ShopType.CricketMall.getIntValue()));
        mallInfoList.addAll(MallMgr.getMallInfoListByShopType(eShopType.PalaceExchangeMall.getValue()));
        for (MallInfo mallInfo : mallInfoList) {
            if (mallInfo.getLimitBuyCount() <= 0) {
                continue;
            }
            int addLimit = calculateRecoveryMallTimes(mallInfo, vipAddParam, offlineDay, param.getIntValue());
            OldPlayerReturnShopLimit shopLimit = mallLimitMap.get(mallInfo.getMallId());
            if (shopLimit != null) {
                shopLimit.setTotalAddLimit(addLimit);
                shopLimit.setHasBuyTimes(0);
            } else {
                OldPlayerReturnShopLimit oldPlayerReturnShopLimit = new OldPlayerReturnShopLimit();
                oldPlayerReturnShopLimit.setUserId(getUserId());
                oldPlayerReturnShopLimit.setHasBuyTimes(0);
                oldPlayerReturnShopLimit.setMallId(mallInfo.getMallId());
                oldPlayerReturnShopLimit.setTotalAddLimit(addLimit);
                oldPlayerReturnShopLimit.setInsertOption();
                mallLimitMap.put(mallInfo.getMallId(), oldPlayerReturnShopLimit);
            }
        }
        //老玩家回归活动商店
        Map<Integer, MallInfo> activityMallInfoMap = NormalActivityMgr.getActivityMallInfoMap(OldPlayerReturnMgr.getActivityInfo().getActivityId());
        if (activityMallInfoMap != null) {
            for (MallInfo mallInfo : activityMallInfoMap.values()) {
                if (mallInfo.getShopType() != eShopType.OldPlayerReturnPlayerMall.getValue()) {
                    continue;
                }


                List<String> stringList = StringUtils.stringToStringList(mallInfo.getExtendParam(), "\\|");
                if (stringList.size() != 2) {
                    continue;
                }

                //配置的除数
                int needOfflineRate = StringUtils.string2intSafe(stringList.get(0), 0);

                //初始值
                int originalLimit = mallInfo.getLimitBuyCount();

                BigDecimal result = BigDecimal.valueOf(originalLimit);
                if (needOfflineRate != 0) {     //需要的离线时间 不是0则加倍

                    BigDecimal maxRate = BigDecimal.valueOf(10);
                    ActivityConfig offlineParameterMax = OldPlayerReturnMgr.getActivity().getConfigMap().get("RETURN_TASK_OFFLINE_PARAMETER_MAX");
                    if (offlineParameterMax != null) {
                        maxRate = BigDecimal.valueOf(offlineParameterMax.getIntValue()).divide(BigDecimal.valueOf(1000), 1, BigDecimal.ROUND_DOWN);
                    }
                    BigDecimal offlineRate = BigDecimal.valueOf(offlineDay).divide(BigDecimal.valueOf(needOfflineRate), 1, BigDecimal.ROUND_DOWN);
                    if (offlineRate.compareTo(maxRate) > 0) {
                        offlineRate = maxRate;
                    }
                    result = result.multiply(offlineRate);
                }

                int needVipAdd = StringUtils.string2intSafe(stringList.get(1), 0);
                if (needVipAdd != 0) {
                    ActivityConfig mall_vip_parameter = OldPlayerReturnMgr.getActivityConfig("RETURN_MALL_VIP_PARAMETER");
                    if (mall_vip_parameter != null) {
                        int vip_parameter = getVipMultiplier(mall_vip_parameter.getValue());
                        result = result.multiply(BigDecimal.valueOf(vip_parameter).divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_DOWN));
                    }
                }

                OldPlayerReturnShopLimit shopLimit = mallLimitMap.get(mallInfo.getMallId());

                int addLimit = result.intValue();
                if (shopLimit != null) {
                    shopLimit.setTotalAddLimit(addLimit);
                    shopLimit.setHasBuyTimes(0);
                } else {
                    OldPlayerReturnShopLimit oldPlayerReturnShopLimit = new OldPlayerReturnShopLimit();
                    oldPlayerReturnShopLimit.setUserId(getUserId());
                    oldPlayerReturnShopLimit.setHasBuyTimes(0);
                    oldPlayerReturnShopLimit.setMallId(mallInfo.getMallId());
                    oldPlayerReturnShopLimit.setTotalAddLimit(addLimit);
                    oldPlayerReturnShopLimit.setInsertOption();
                    mallLimitMap.put(mallInfo.getMallId(), oldPlayerReturnShopLimit);
                }

            }
        }
    }

    /**
     * 通过conditionId获取真实奖励
     */
    public Property getRealLogineward(int conditionId) {
        Property finalReward = new Property();
        if (OldPlayerReturnMgr.getNowActivityType() != OldPlayerReturnActivityType.NEW_ACTIVITY.getValue()) {
            return finalReward;
        }
        OldPlayerReturnTaskRewardData taskReward = conditionRewardMap.get(conditionId);
        if (taskReward == null) {
            return finalReward;
        }
        List<OldPlayerReturnAddtionGood> conditionReward = taskReward.getConditionReward();
        for (OldPlayerReturnAddtionGood singleGood : conditionReward) {
            finalReward.addProperty(PropertyHelper.parseStringToProperty(singleGood.getReward()));
        }

        return finalReward;
    }


    /**
     * 生成活动任务特殊登录奖励
     */


    /**
     * 生成每日登录特殊奖励
     */
    public void generateReturnUserLoginReward(boolean force) {
        ActivityInfo activityInfo = OldPlayerReturnMgr.getActivityInfo();
        if (!ActivityMgr.activityInTime(activityInfo)) {
            return;
        }
        //如果已经有了 看看是不是这次活动的
        boolean hasThisActivityData = false;
        if (!conditionRewardMap.isEmpty()) {
            for (OldPlayerReturnTaskRewardData taskReward : conditionRewardMap.values()) {
                if (taskReward.getActivityId() == activityInfo.getActivityId()) {
                    hasThisActivityData = true;
                }
            }
        }
        if (hasThisActivityData && !force) {
            return;
        }

        BaseActivityData baseActivityData = player.getModule(ActivityModule.class).getBaseActivityData(activityInfo.getActivityId());
        UserActivityConditionData firstUserActivityConditionDataByType = baseActivityData.getFirstUserActivityConditionDataByType(eGamePlayerEventType.OldPlayerReturnOfflineDays.getValue());
        if (firstUserActivityConditionDataByType == null) {
            return;
        }
        BigDecimal offlineRate = getTaskOfflineRate();
        //tmp奖励map
        Map<Integer, OldPlayerReturnTaskRewardData> tmpRewardMap = new HashMap<>();
        List<ActivityConditionInfo> infoList = NormalActivityMgr.getActivityConditionInfoListByType(activityInfo.getActivityId(), eGamePlayerEventType.LoginDays.getValue());
        Map<Integer, List<OldPlayerReturnDayLoginTaskConfig>> loginTaskConfigMap = OldPlayerReturnMgr.getActivity().getLoginTaskConfigMap();

        for (ActivityConditionInfo activityConditionInfo : infoList) {
            //拿出天数
            int loginSpecialDay = activityConditionInfo.getParamList().get(2).intValue();


            List<OldPlayerReturnDayLoginTaskConfig> oldPlayerReturnDayLoginTaskConfigList = loginTaskConfigMap.get(loginSpecialDay);
            if (oldPlayerReturnDayLoginTaskConfigList == null) {
                log.error("重归汴梁活动{}每日登录奖励第{}日任务配置有误", activityInfo.getActivityId(), loginSpecialDay);
                return;
            }

            OldPlayerReturnTaskRewardData taskReward = new OldPlayerReturnTaskRewardData();
            taskReward.setConditionReward(new ArrayList<>());
            boolean isFirst = true;
            for (OldPlayerReturnDayLoginTaskConfig config : oldPlayerReturnDayLoginTaskConfigList) {
                if (isFirst) {
                    isFirst = false;
                    Property singleProperty = new Property(config.getItemId(), config.getBaseNum());
                    OldPlayerReturnAddtionGood good = new OldPlayerReturnAddtionGood(PropertyHelper.parsePropertyToString(singleProperty), 1000);
                    taskReward.getConditionReward().add(good);
                    continue;
                }
                int vipMultiplier = getVipMultiplier(config.getVipParameter());
                BigDecimal rate = offlineRate.multiply(BigDecimal.valueOf(vipMultiplier).divide(BigDecimal.valueOf(1000))).setScale(1, BigDecimal.ROUND_DOWN);
                long trueNum = rate.multiply(BigDecimal.valueOf(config.getBaseNum())).setScale(0, BigDecimal.ROUND_DOWN).longValue();
                Property singleProperty = new Property(config.getItemId(), trueNum);
                OldPlayerReturnAddtionGood good = new OldPlayerReturnAddtionGood(PropertyHelper.parsePropertyToString(singleProperty), rate.multiply(BigDecimal.valueOf(1000)).setScale(0, BigDecimal.ROUND_DOWN).intValue());
                taskReward.getConditionReward().add(good);
            }
            taskReward.setActivityId(activityInfo.getActivityId());
            taskReward.setUserId(getUserId());
            taskReward.setConditionId(activityConditionInfo.getConditionId());
            if (hasThisActivityData && conditionRewardMap.get(activityConditionInfo.getConditionId()) != null) {
                taskReward.setUpdateOption();
            } else {
                taskReward.setInsertOption();
            }
            tmpRewardMap.put(taskReward.getConditionId(), taskReward);
        }
        List<ActivityConditionInfo> activityConditionInfoList = NormalActivityMgr.getActivityConditionInfoList(activityInfo.getActivityId());
        //拿出需要特殊处理的
        for (ActivityConditionInfo activityConditionInfo : activityConditionInfoList) {
            if (activityConditionInfo.getRewardStr().equals("0")) {
                continue;
            }
            if (activityConditionInfo.getType() == eGamePlayerEventType.LoginDays.getValue()) {
                continue;
            }
            if (OldPlayerReturnMgr.checkAcitvityNeedSpecialReward(activityConditionInfo.getType())) {
                OldPlayerReturnTaskRewardData taskReward = new OldPlayerReturnTaskRewardData();
                taskReward.setConditionReward(new ArrayList<>());

                List<String> stringList = StringUtils.stringToStringList(activityConditionInfo.getRewardStr(), ";");
                //第一个特殊处理
                String firstReward = stringList.get(0);
                OldPlayerReturnAddtionGood firstRewardGood = new OldPlayerReturnAddtionGood(firstReward, 1000);
                taskReward.getConditionReward().add(firstRewardGood);
                stringList.remove(0);
                for (String reward : stringList) {
                    List<String> idNumList = StringUtils.stringToStringList(reward, "=");
                    if (idNumList.size() != 2) {
                        continue;
                    }
                    int originNum = StringUtils.string2intSafe(idNumList.get(1), 0);
                    long result = offlineRate.multiply(BigDecimal.valueOf(originNum)).setScale(0, BigDecimal.ROUND_DOWN).longValue();

                    String idString = idNumList.get(0);
                    int id = StringUtils.string2intSafe(idString, 0);
                    Property rewardProperty = new Property(id, result);
                    OldPlayerReturnAddtionGood good = new OldPlayerReturnAddtionGood(PropertyHelper.parsePropertyToString(rewardProperty), offlineRate.multiply(BigDecimal.valueOf(1000)).setScale(0, BigDecimal.ROUND_DOWN).intValue());
                    taskReward.getConditionReward().add(good);
                }
                taskReward.setActivityId(activityInfo.getActivityId());
                taskReward.setUserId(getUserId());
                taskReward.setConditionId(activityConditionInfo.getConditionId());

                if (hasThisActivityData && conditionRewardMap.get(activityConditionInfo.getConditionId()) != null) {
                    taskReward.setUpdateOption();
                } else {
                    taskReward.setInsertOption();
                }
                tmpRewardMap.put(taskReward.getConditionId(), taskReward);
            }
        }

        conditionRewardMap = tmpRewardMap;
    }


    public int calculateRecoveryMallTimes(MallInfo mallInfo, int vipAdd, int offlineDay, int offlineParam) {
        if (mallInfo.getLimitBuyCount() <= 0) {
            return 0;
        }
        BigDecimal offlineRate = BigDecimal.valueOf(offlineDay).divide(BigDecimal.valueOf(offlineParam), 1, BigDecimal.ROUND_DOWN);
        BigDecimal maxRate = BigDecimal.valueOf(10);
        ActivityConfig offlineParameterMax = OldPlayerReturnMgr.getActivity().getConfigMap().get("RETURN_TASK_OFFLINE_PARAMETER_MAX");
        if (offlineParameterMax != null) {
            maxRate = BigDecimal.valueOf(offlineParameterMax.getIntValue()).divide(BigDecimal.valueOf(1000), 1, BigDecimal.ROUND_DOWN);
        }

        if (offlineRate.compareTo(maxRate) > 0) {
            offlineRate = maxRate;
        }
        if (mallInfo.getLimitBuyType() == eLimitBuyType.MONTH.getValue()) {
            // 限购次数 * 折损比(千分比) * vip倍数(千分比)  * 离线天数 / 1000 /1000 /一个月
            return offlineRate.multiply(BigDecimal.valueOf(mallInfo.getLimitBuyCount() * vipAdd / 30 / 1000)).setScale(0, BigDecimal.ROUND_DOWN).intValue();
        }
        if (mallInfo.getLimitBuyType() == eLimitBuyType.WEEK.getValue()) {
            return offlineRate.multiply(BigDecimal.valueOf(mallInfo.getLimitBuyCount() * vipAdd / 7 / 1000)).setScale(0, BigDecimal.ROUND_DOWN).intValue();

        }
        if (mallInfo.getLimitBuyType() == eLimitBuyType.DAILY.getValue()) {
            return offlineRate.multiply(BigDecimal.valueOf(mallInfo.getLimitBuyCount() * vipAdd / 1000)).setScale(0, BigDecimal.ROUND_DOWN).intValue();
        }
        return 0;
    }

    public boolean checkUserIsReturn() {
        OldPlayerReturnUserData userData = OldPlayerReturnMgr.getUserData(getUserId());
        ActivityInfo activityInfo = OldPlayerReturnMgr.getActivityInfo();
        //活动不存在
        if (!ActivityMgr.activityInTime(activityInfo)) {
            return false;
        }
        //不是回归玩家
        if (userData == null || !userData.isReturn()) {
            return false;
        }
        //回归有效期已经过了
        if (!OldPlayerReturnMgr.checkReturnEffectiveTime(userData.getReturnTime())) {
            return false;
        }
        //不是这个活动触发的回归
        if (activityInfo.getActivityId() != userData.getActivityId()) {
            return false;
        }
        return true;
    }

    public OldPlayerReturnShopLimit getOldPlayerReturnShopLimit(int mallId) {
        return mallLimitMap.get(mallId);
    }

    public boolean reduceRecoverMallTime(int mallId, int count) {
        OldPlayerReturnShopLimit oldPlayerReturnShopLimit = getOldPlayerReturnShopLimit(mallId);
        if (oldPlayerReturnShopLimit == null) {
            return false;
        }
        if (oldPlayerReturnShopLimit.getHasBuyTimes() + count > oldPlayerReturnShopLimit.getTotalAddLimit()) {
            oldPlayerReturnShopLimit.setHasBuyTimes(oldPlayerReturnShopLimit.getTotalAddLimit());
            log.error("回归玩家{}找回商店{}次数超出限制", getUserId(), mallId);
            return true;
        }
        oldPlayerReturnShopLimit.setHasBuyTimes(oldPlayerReturnShopLimit.getHasBuyTimes() + count);
        return true;
    }

    public int getVipMultiplier(String vipParam) {
        int userVipLv = VipMgr.getVipLv(player.getUserInfo().getVipExp());
        List<String> stringListValue = StringUtils.stringToStringList(vipParam, "\\|");
        int maxVipLevel = 0;
        int vipAddParam = 1000;
        for (String vipValueString : stringListValue) {
            List<String> stringList = StringUtils.stringToStringList(vipValueString, ",");
            int level = StringUtils.parseInt(stringList.get(0));
            if (userVipLv >= level && level >= maxVipLevel) {
                maxVipLevel = level;
                vipAddParam = StringUtils.parseInt(stringList.get(1));
            }
        }
        return vipAddParam;
    }

    public void forceResetTaskAndLimitData() {

    }

}
